import * as vscode from 'vscode';
import { sortOrder } from "./csscomb";


export type AstTree = Array<{
  value:string
  children?:AstTree
  // order?: number
  [p:string]:any
}>;

/* 将style字符串解析为ast */
export const parseStr = (str:string) => {
  const s1 = str.replace(/ +/g,' ').replace(/@\{(.*)\}/g, '@_[_$1_]_').replace(/};/g,'}').replace(/{/g,' {').replace(/\s*;/g,';\n');
  const lines = s1.replace(/(\r|\n| )+{/g,' {\n').replace(/}/g,'\n}\n').split('\n').filter(n=> n !=='\r' && n !== '' && !/^\s+$/.test(n));
  const ast:AstTree = [];
  const stack: AstTree = [];
  let temp = '';
  lines.forEach((s)=>{
    const s1 = s.split('{')[0];
    const s2 = s.split('}')[0];
    if(!s1.includes('//') && !s1.includes('/*') && s.includes('{')){
      stack.push({value:s, children: []});
    }else if(!s2.includes('//') && !s2.includes('/*') && s.includes('}')){
      const end = stack.pop() as AstTree[number];
      if(stack.length === 0){
        ast.push(end);
        ast.push({value: '}'});
      }else{
        stack?.[stack.length - 1].children?.push(end);
        stack?.[stack.length - 1].children?.push({value: '}'});
      }
    }else {
      const ts = s.replace(/(\/\/|\/\*).*/,'').trim();
      if(/:$/.test(ts)){
        temp = ts;
        return;
      }
      if(stack.length > 0){
        stack[stack.length - 1].children?.push({value: temp + s});
      }else{
        ast.push({value: temp + s});
      }
      temp = '';
    }
  });
  return ast;
};

/** 使用ast格式化后转为文本 start:表示格式化最外层有几个tab */
export const format = (ast:AstTree,start = 0) => {
  const tabSize = vscode.workspace.getConfiguration().get('editor.tabSize') as number || 2;
  let strArr:string[] = [];
  const fn = (ast:AstTree,i = 0) => {
    ast.forEach((a)=>{
      let s1 = '';
      for (let j = 0; j < i * tabSize; j++) {
          s1 += ' '; 
      }
      const s2 = a.value.trim();
      const s3 = s2.includes(':') && s2.includes(';') ?  s2.split(':').map(x=>x.trim()).join(': ') : s2;
      strArr.push(s1 + s3);
      if(a.children){
        fn(a.children, i + 1);
      }
    });
  };
  fn(orderFn(ast), start);
  return strArr.join('\n').replace(/@_\[_(.*)_\]_/g, '@{$1}');
};
/** css属性排序格式化 */
const orderFn = (ast:AstTree): AstTree => {
  const fn = (children:AstTree) => {
    children.forEach(v=>{
      if(v.value.includes(':') && v.value.includes(';')){
        const p = v.value.split(':')?.[0].trim();
        const order = sortOrder.indexOf(p);
        if(order >=0){
          v.order = order;
        }else{
          v.order = 9999;
        }
      }else{
        v.order = 99999;
      }
      if(v.children){
        fn(v.children);
      }
    });
    children = children.sort((a,b)=> a.order - b.order);
  };
  ast.forEach(a=>{
    if(a.children){
      fn(a.children);
    }
  });
  return ast;
};
